import { Handler } from "../../components/Handler";
import { LogMgr } from "../../components/LogMgr";
import { ApiUrl } from "../../env/ApiEnv";
import { HttpDataBase } from "./HttpDataBase";

export enum ErrorCode {
    NetworkError = "NetworkError",//网络错误
    UserBanned = 'UserBanned',// 用户禁用
    VerificationFailed = 'VerificationFailed',//验证失败
    ServerDown = 'ServerDown',//停服维护
}

export class HttpClient {
    private static _timeout: number = 5000; // 假设默认超时时间为 5 秒 
    private static _reconnectTim:number = 4000;//多少时间内会重连
    private static _intervalTime:number = 500;//重连间隔时间
    private static _noVerifyUrl:Array<string> = ['/account/visitor-login', '/account/nickname-login','/home/app-config',
                                                 '/account/third-login', '/account/check-token', '/report-issue/create', '/report-issue/self-list'];
    private static PONE: Array<HttpClient> = [];
    private _timeoutId: number;
    private _reconnectTimId:number;
    private _intervalTimeID:number;
    private _url:string;
    private _data:any;
    private _fetchOptions:any;
    private _callbackHandler: Handler<any> | null = null;
    private _method:string;
    private _isReconnectTim:boolean;
    private _isOver:boolean;
    public static getObject(): HttpClient {
        if (HttpClient.PONE.length > 0) {
            return HttpClient.PONE.pop()!;
        } else {
            return new HttpClient();
        }
    }
    public sendRequest(method: 'GET' | 'POST', pathSuffix: string, callbackHandler: Handler<any>, data: any | null = null, contentType: string = 'application/json' ): void {
        this._callbackHandler = callbackHandler;
        this._url = this.getUrl(pathSuffix);
        this._data = data;
        this._method = method;
        this._isReconnectTim = true;
        this._fetchOptions =  {};
        let token:string
        if(HttpClient._noVerifyUrl.indexOf(pathSuffix)==-1)
        {
            token = "";
            if(!token)
            {
                LogMgr.error("token异常");
                return;
            }
        }
        if (method === 'POST') {
            this._fetchOptions = {
                method: 'POST',
                headers: {
                    'Content-Type': contentType,
                    'Authorization': `Bearer ${token}` 
                },
                body: data ? JSON.stringify(data) : undefined,
            };
        }else {
            this._fetchOptions = {
                method: "GET",
                headers: {
                    'Content-Type': contentType,
                    'Authorization': `Bearer ${token}`
                },
            };
        }
        this._reconnectTimId = setTimeout(()=>{
            this._isReconnectTim = false;
    },HttpClient._reconnectTim)
        this._timeoutId = setTimeout(() => {
            clearTimeout(this._intervalTimeID);
            this.networkError(this._url);
        }, HttpClient._timeout);
        this.startFatch();
    }
    private startFatch():void{
        this._isOver = false;
        fetch(this._url, {
            ...this._fetchOptions,
          })
            .then((response: Response) => {
                  if (!response.ok) {
                    if(this._isReconnectTim)
                    {
                        this.reconnect();
                    }else{
                        this.networkError(this._url)
                    }
                    return;
                  }
                  return response.json(); 
              })
            .then((responseData:CommonResult) => {
                this._isOver = true;
                  LogMgr.log("收到http返回>>",responseData);
                  let data: HttpDataBase<any> = new HttpDataBase();
                  if (responseData) {
                        if(responseData.success)
                        {
                            data.data = responseData.data;
                            data.isSuccessful = true;
                        }else{
                            data.isSuccessful = false;
                            if(responseData.code==110002)
                            {
                                data.errorCode = ErrorCode.UserBanned;
                            }else if(responseData.code==100003)
                            {
                                data.errorCode = ErrorCode.ServerDown;
                            }else{
                                data.errorCode = ErrorCode.VerificationFailed;
                            }
                            data.errorMsg = responseData.message;
                        }
                  } else {
                        data.isSuccessful = false;
                        data.errorCode = ErrorCode.VerificationFailed;
                        data.data = "responseData>>"+responseData;
                  }
                  this.handleCallback(data);
              })
            .catch((error) => {
                LogMgr.error(error);
                if(!this._isOver)//防止代码异常跑进来
                {
                    if(this._isReconnectTim)
                        {
                            this.reconnect();
                        }else{
                            this.networkError(this._url);
                        }
                }else{
                    this.release();
                }
              });
    }
    private handleCallback(data: HttpDataBase<any>): void {
        if(data.isSuccessful)
        {
            LogMgr.log("服务器返回成功 >> errorCode= " + data.errorCode + ">>" + data.data);
        }else{
            if(data.errorCode==ErrorCode.NetworkError)
            {
                LogMgr.log("网络异常")
            }
        }
        if (this._callbackHandler) {
            this._callbackHandler.runWith(data);
            this._callbackHandler.clear();
            this._callbackHandler = null;
        }
        this.release();
    }

    private getUrl(pathSuffix: string): string {
        return ApiUrl + pathSuffix;
    }
    private reconnect():void{
        this._intervalTimeID = setTimeout(() => {
            this.startFatch();
        }, HttpClient._intervalTime);
    }
    private networkError(url: string): void {
        LogMgr.log("网络异常请求失败 url=" + url);
        let data: HttpDataBase<any> = new HttpDataBase();
        data.isSuccessful = false;
        data.errorMsg = "NetworkError";
        data.errorCode = ErrorCode.NetworkError;
        this.handleCallback(data);
    }
    // 释放 HttpClient 实例到对象池中
    private release(): void {
        if (this._timeoutId) {
            clearTimeout(this._timeoutId);
            this._timeoutId = 0;
        }
        if (this._intervalTimeID) {
            clearTimeout(this._intervalTimeID);
            this._intervalTimeID = 0;
        }
        this._callbackHandler = null;
        HttpClient.PONE.push(this);
    }
}
interface CommonResult {
    /** 请求是否成功 */
    success: boolean;
    /** 业务错误代码，请求成功时此项为 0 */
    code: number;
    /** 业务错误提示文本，请求成功时此项为 '' */
    message: string;
    /** 数据 '' */
    data?: any;
  }